#include <stdio.h>
#include <sys/io.h>

/*
  connections:
  STROBE   --> CLK
  AUTOFEED --> CLR
  ERR <------- DATA
 */

/* parallel port address */
#define port_base       0x3bc
#define port_status     port_base + 1
#define port_control    port_base + 2
/* data byte out */
#define port_out(byte)  outb_p(byte,port_base)
/* control register bits */
#define update_ctl      outb_p(ctrport,port_control)
#define update_dat      port_out(datport)
#define STROBE_HIGH	ctrport &= ~0x01; update_ctl  /* inverted */
#define STROBE_LOW	ctrport |= 0x01; update_ctl   /* inverted */
#define AUTOFEED_HIGH	ctrport &= ~0x02; update_ctl /* inverted */
#define AUTOFEED_LOW	ctrport |= 0x02; update_ctl  /* inverted */
/* needed status register bits */
#define ERR             0x08
#define bit_in          (inb_p(port_status) & ERR)

/* functions */
#define CLK_HIGH        STROBE_HIGH
#define CLK_LOW         STROBE_LOW
#define CHIP_CLR        AUTOFEED_LOW
#define CHIP_ENABLE     AUTOFEED_HIGH

/* parallel port direction control */
#define PCD	        0x20
#define port_write      ctrport &= ~PCD; update_ctl
#define port_read       ctrport |= PCD; update_ctl

static unsigned char ctrport, datport=0;

static void init_port() /* Initialize parallel port */
{
  if (ioperm(port_base,3,1))
  {
    fprintf(stderr, "Error: Couldn't get the port at %x\n", port_base);
    fprintf(stderr, "Note: you MUST run this program as root.\n");
    exit(1);
  }
  ioperm(0x80,3,1);
  ctrport = inb(port_control);
  port_write;
  update_dat;
}


int main()
{
  unsigned int i;
  char b;
  init_port();	
  CHIP_CLR; /* reset keyboard */
  CLK_LOW;  /* clock initially off */
  sleep(1); /* reset delay */  
  CHIP_ENABLE; /* enable keyboard */	
  /*nanosleep(500);*/
  while (1)
  {
	  printf("BEGINNING SCAN\n");
	  for (i=0; i<=512; i++)
	  {
	    b = bit_in;
	    printf("bit %d = %d\n", i, b);
	    CLK_HIGH;
	    nanosleep(500);
	    CLK_LOW;
	    nanosleep(500);
	  }	    
  }    
  return 0;
}
